require("./common")

// const moment = require('moment');
// 监听 mock 目录（/mock，而不是 /src/mock）。
const chokidar = require('chokidar')
const path = require('path')

const mockRoutes = require("./development")
// console.log('mockRoutes', mockRoutes);

const Mock = require('mockjs')
const bodyParser = require('body-parser')

// 绝对路径
const mockDir = path.join(process.cwd(), 'mock'+ path.sep + 'development')

// 处理各个模块监听的路由和响应
const responseFake = (url, type, respond) => {
  return {
    url: new RegExp(`${process.env.VUE_APP_BASE_API_CONTEXT}${url}`),
    type: type || 'get',
    response(req, res) {
      console.log('request invoke: ' + req.path)
      res.json(Mock.mock(respond instanceof Function ? respond(req, res) : respond))
    }
  }
}

// 监听各个接口（这里，mock 下的各个模块内不需要监听了，而是在这个函数内统一处理）
function registerMockRoutes(app) {
  var mockRoutesLastIndex = 0;
  var mockRoutesLength = 0;

  // 最终监听的各个路由
  var finalMockRoutes = mockRoutes.map( route => {
    return responseFake(route.url, route.type, route.response)
  })

  // app._router.stack.length 初始是有值的，在测试中是 11。
  // console.log('app._router.stack A', app._router.stack.length);

  // 监听
  for (var mockRoute of finalMockRoutes) {
    app[mockRoute.type](mockRoute.url, mockRoute.response)
    // console.log('app._router.stack -', app._router.stack.length);
    // 每监听一个URL，app._router.stack.length 就会 +1。
    mockRoutesLastIndex = app._router.stack.length
    mockRoutesLength++
  }

  // console.log('app._router.stack B', app._router.stack.length);
  // console.log('app._router.stack B', app._router.stack);

  return {
    mockRoutesLength,
    // 计算第一个自定义的 mock URL 在 app._router.stack 的索引。
    mockRoutesStartIndex: mockRoutesLastIndex - mockRoutesLength
  }
}

// 取消监听
function unregisterMockRoutes() {
  Object.keys(require.cache).forEach(i => {
    if (i.includes(mockDir)) {
      delete require.cache[require.resolve(i)]
    }
  })
}

module.exports = function (app) {
  console.log("/mock/index.js >> process.env.VUE_APP_API_MOCK", process.env.VUE_APP_API_MOCK);
  /*
  console.log("/mock/index.js >> app", app);
  function (req, res, next) {
    app.handle(req, res, next);
  }
  */

  app.use(bodyParser.json())

  const mockRoutesData = registerMockRoutes(app)
  var mockRoutesLength = mockRoutesData.mockRoutesLength
  var mockRoutesStartIndex = mockRoutesData.mockRoutesStartIndex

  // 监听 mock 的变化
  chokidar.watch(mockDir, {
    ignored: /mock-env/,
    ignoreInitial: true
  }).on('all', (event, path) => {
    if (event === 'change' || event === 'add') {
      try {
        // remove mock routes stack
        app._router.stack.splice(mockRoutesStartIndex, mockRoutesLength)

        // 清理 mock 路由缓存
        unregisterMockRoutes()

        const mockRoutesData2 = registerMockRoutes(app)
        mockRoutesLength = mockRoutesData2.mockRoutesLength
        mockRoutesStartIndex = mockRoutesData2.mockRoutesStartIndex

        console.log(chalk.magentaBright(`\n > Mock Server hot reload success! changed  ${path}`))
      } catch (error) {
        console.log(chalk.redBright(error))
      }
    }
  })
};
